package com.SmartCare.service.impl.diet;

import com.SmartCare.pojo.diet.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.SmartCare.common.enums.Constants;
import com.SmartCare.common.Result;
import com.SmartCare.common.exception.ServiceException;
import com.SmartCare.common.enums.FoodType;
import com.SmartCare.service.diet.DietRecordService;
import com.SmartCare.common.vo.diet.DietBreakfastVo;
import com.SmartCare.common.dto.diet.DietBreakfastDTO;
import com.SmartCare.common.vo.diet.OthersVo;
import com.SmartCare.mapper.role.ElderlyInformationMapper;
import com.SmartCare.mapper.diet.DietRecordMapper;
import com.SmartCare.pojo.role.ElderlyInformation;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.SmartCare.utils.DateTimeUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 餐饮记录表 服务实现类
 */
@Service
public class DietRecordServiceImpl extends ServiceImpl<DietRecordMapper, DietRecord> implements DietRecordService {

    @Resource
    ElderlyInformationMapper eim;

    @Override
    public Result addLunch(Lunch lunch) {

        ElderlyInformation one = getElderlyInformation(lunch.getElderId());

        LocalDate currentDate = DateTimeUtils.getCurrentDateTime();
        LocalDateTime startTime = LocalDateTime.of(currentDate, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(currentDate, LocalTime.MAX);
        LambdaQueryWrapper<DietRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DietRecord::getElderlyId, lunch.getElderId());
        wrapper.between(DietRecord::getCreatedTime, startTime, endTime);
        wrapper.eq(DietRecord::getLunchFlag, 1);
        long res = super.count(wrapper);
        if (res > 0) {
            return Result.error("重复添加");
        }

        //将五个Food对象集合和一个Other对象集合转为数据库可存的DietRecord对象
        conversionTool(FoodType.FOOD.getValue(), lunch.getStapleFood(), one.getElderlyId(),"lunch");
        conversionTool(FoodType.ASSISTED_FOOD.getValue(), lunch.getAssistedFood(), one.getElderlyId(),"lunch");
        conversionTool(FoodType.MEAT.getValue(), lunch.getMeatDishs(), one.getElderlyId(),"lunch");
        conversionTool(FoodType.VEGETABLE.getValue(), lunch.getVegetableDishs(), one.getElderlyId(),"lunch");
        conversionTool(FoodType.SOUP.getValue(), lunch.getSoup(), one.getElderlyId(),"lunch");
        //处理Others对象
        for (Others o : lunch.getOthers()) {
            DietRecord d = new DietRecord();
            //设置相关属性值
            d.setElderlyId(one.getElderlyId());
            d.setOthers(o.getContent());
            d.setLunchFlag(1);
            d.setDietType(FoodType.OTHERS.getValue());
            d.setPicture(o.getPicture());
            //存入数据库
            save(d);
        }
        return Result.success();
    }

    /**
     * 先获取老人对象并判空
     */
    private ElderlyInformation getElderlyInformation(Long elderId) {
        ElderlyInformation one = eim.selectOne(new QueryWrapper<ElderlyInformation>().eq("elderly_id", elderId));
        if (one == null) {
            throw new ServiceException(Constants.CODE_400, "老人ID不存在");
        }
        return one;
    }

    /**
     * 将Food对象转为DietRecord对象并存入数据库的辅助工具
     * @param dietType 枚举类型
     * @param food     进行转化的Food对象
     * @param elderId  老人id
     */
    public void conversionTool(Integer dietType, List<Food> food, Long elderId, String mealType) {
        for (Food f : food) {
            DietRecord d = new DietRecord();
            //设置相关属性值
            d.setElderlyId(elderId);
            d.setName(f.getName());
            d.setCount(f.getCount());
            if (mealType.equals("lunch")) {
                d.setLunchFlag(1); //午餐
            } else if (mealType.equals("dinner")) {
                d.setDinnerFlag(1); //晚餐
            }
            d.setDietType(dietType);
            //存入数据库
            save(d);
        }
    }

    @Override
    public Result getLunch(Long elderId, String date) {
        getElderlyInformation(elderId);

        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate d = LocalDate.parse(date, df);
        LocalDateTime startTime = LocalDateTime.of(d, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(d, LocalTime.MAX);

        //获取该老人的所有午餐记录
        QueryWrapper<DietRecord> qw = new QueryWrapper<>();
        qw.eq("elderly_id", elderId);
        qw.eq("lunch_flag", 1);
        qw.between("created_time", startTime, endTime);
        List<DietRecord> records = list(qw);

        //使用Map来进行按照创建时间分组
        Map<LocalDateTime, List<DietRecord>> recordsByTime = records.stream()
                .collect(Collectors.groupingBy(DietRecord::getCreatedTime));

        List<Lunch> lunchList = new ArrayList<>();

        //遍历分组后的记录，构造Lunch对象并添加到集合中
        for (Map.Entry<LocalDateTime, List<DietRecord>> entry : recordsByTime.entrySet()) {
            LocalDateTime createdTime = entry.getKey();
            List<DietRecord> recordsForTime = entry.getValue();

            //新建lunch对象并初始化
            Lunch lunch = new Lunch();
            lunch.setElderId(elderId);
            lunch.setCreatedTime(createdTime);
            lunch.setStapleFood(new ArrayList<>());
            lunch.setAssistedFood(new ArrayList<>());
            lunch.setMeatDishs(new ArrayList<>());
            lunch.setVegetableDishs(new ArrayList<>());
            lunch.setSoup(new ArrayList<>());
            lunch.setOthers(new ArrayList<>());

            for (DietRecord record : recordsForTime) {
                //根据record的dietType，将食物添加到对应的列表中
                switch (record.getDietType()) {
                    case -1:
                        Others other = new Others();
                        other.setId(record.getId());
                        other.setContent(record.getOthers());
                        other.setPicture(record.getPicture());
                        lunch.getOthers().add(other);
                        break;
                    case 2:
                        lunch.getStapleFood().add(createFoodFromRecord(record));
                        break;
                    case 3:
                        lunch.getAssistedFood().add(createFoodFromRecord(record));
                        break;
                    case 4:
                        lunch.getMeatDishs().add(createFoodFromRecord(record));
                        break;
                    case 5:
                        lunch.getVegetableDishs().add(createFoodFromRecord(record));
                        break;
                    case 6:
                        lunch.getSoup().add(createFoodFromRecord(record));
                        break;
                    default:
                        throw new ServiceException(Constants.CODE_500, "枚举类型错误");
                }
            }

            lunchList.add(lunch);
        }

        //对Lunch对象集合按创建时间排序
        Collections.sort(lunchList);
        return Result.success(lunchList);
    }

    /**
     * 早晚餐信息查询
     */
    @Override
    public Result breAndDinQuery(Long elderId, HttpServletRequest request, String date) {
        String uri = request.getRequestURI();
        LocalDate currentDate = LocalDate.parse(date);
        LocalDateTime startTime = LocalDateTime.of(currentDate, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(currentDate, LocalTime.MAX);

        //早餐查询返回的对象
        DietBreakfastVo dietBreakfastVo = new DietBreakfastVo();


        //遍历食物类型，依次查询数据
        for (FoodType foodType : FoodType.values()) {
            LambdaQueryWrapper<DietRecord> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DietRecord::getElderlyId, elderId);
            if (uri.contains("breakfast_query")) {
                queryWrapper.eq(DietRecord::getBreakfastFlag, 1);
            } else if (uri.contains("dinner_query")) {
                queryWrapper.eq(DietRecord::getDinnerFlag, 1);
            }
            queryWrapper.eq(DietRecord::getDietType, foodType.getValue());
            queryWrapper.between(DietRecord::getCreatedTime, startTime, endTime);

            List<DietRecord> list = super.list(queryWrapper);

            //匹配饮食类型进行返回对象的封装
            switch (foodType) {
                case DRINK:
                    dietBreakfastVo.setDrinkList(getVoList(list));
                    continue;
                case EGGMILK:
                    dietBreakfastVo.setEggMilkList(getVoList(list));
                    continue;
                case ASSISTED_FOOD:
                    dietBreakfastVo.setAssistedFood(getVoList(list));
                    continue;
                case FOOD:
                    dietBreakfastVo.setFoodList(getVoList(list));
                    continue;
                case OTHERS:
                    List<OthersVo> othersListVo = new ArrayList<>();
                    for (DietRecord dietRecord : list) {
                        OthersVo othersVo = new OthersVo();
                        BeanUtils.copyProperties(dietRecord, othersVo, "picture");
                        othersVo.setPicture(Arrays.asList(dietRecord.getPicture().split(";")));
                        othersListVo.add(othersVo);
                    }
                    dietBreakfastVo.setOthers(othersListVo);
            }
        }
        if (dietBreakfastVo.isEmpty()) {
            return Result.success("无记录");
        }
        return Result.success(dietBreakfastVo);
    }


    /**
     * 食物返回对象封装
     */
    private static List<Food> getVoList(List<DietRecord> list) {
        List<Food> foodList = new ArrayList<>();
        for (DietRecord dietRecord : list) {
            Food food = new Food();
            BeanUtils.copyProperties(dietRecord, food);
            foodList.add(food);
        }
        return foodList;
    }

    /**
     * 创建食物类的辅助工具
     * @param record 数据库中的餐饮记录
     * @return 返回Food类
     */
    private Food createFoodFromRecord(DietRecord record) {
        Food food = new Food();
        food.setId(record.getId());
        food.setName(record.getName());
        food.setCount(record.getCount());
        return food;
    }

    /**
     * 早餐、晚餐饮食记录添加（旧）
     */
    @Override
    public Result breAndDinAdd(DietBreakfastDTO dietBreakfastDto, HttpServletRequest request) {

        // 空值处理
        if (dietBreakfastDto == null) {
            return Result.error("请求数据不能为空");
        }
        // 空值处理
        if (dietBreakfastDto.getElderId() == null) {
            return Result.error("老人ID不能为空");
        }

        getElderlyInformation(dietBreakfastDto.getElderId());

        //不同类型饮食类型列表的获取
        Long elderId = dietBreakfastDto.getElderId();
        List<Food> drinkList = dietBreakfastDto.getDrinkList();
        List<Food> assistedFood = dietBreakfastDto.getAssistedFood();
        List<Food> eggMilkList = dietBreakfastDto.getEggMilkList();
        List<Food> foodList = dietBreakfastDto.getFoodList();
        List<Others> others = dietBreakfastDto.getOthers();

        //查询是否存在记录，如果存在添加失败
        LocalDate currentDate = DateTimeUtils.getCurrentDateTime();
        LocalDateTime startTime = LocalDateTime.of(currentDate, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(currentDate, LocalTime.MAX);

        LambdaQueryWrapper<DietRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DietRecord::getElderlyId, elderId);
        wrapper.between(DietRecord::getCreatedTime, startTime, endTime);

        String uri = request.getRequestURI();
        if (uri.contains("breakfast_add")) {
            // 处理早餐相关逻辑
            wrapper.eq(DietRecord::getBreakfastFlag, 1);
        } else if (uri.contains("dinner_add")) {
            // 处理晚餐相关逻辑
            wrapper.eq(DietRecord::getDinnerFlag, 1);
        }
        long recodeNums = super.count(wrapper);
        if (recodeNums > 0) {
            return Result.error("重复添加");
        }

        List<DietRecord> dietRecords = new ArrayList<>();

        getDietRecords(drinkList, FoodType.DRINK.getValue(), dietRecords, elderId, request);
        getDietRecords(assistedFood, FoodType.ASSISTED_FOOD.getValue(), dietRecords, elderId, request);
        getDietRecords(eggMilkList, FoodType.EGGMILK.getValue(), dietRecords, elderId, request);
        getDietRecords(foodList, FoodType.FOOD.getValue(), dietRecords, elderId, request);
        getDietRecords(others, FoodType.OTHERS.getValue(), dietRecords, elderId, request);

        //添加数据
        super.saveBatch(dietRecords);

        return Result.success("添加成功");
    }

    /**
     * 晚餐记录添加（新）
     */
    @Override
    public Result addDinner(Dinner dinner) {
        ElderlyInformation elder = getElderlyInformation(dinner.getElderId());

        LocalDate currentDate = DateTimeUtils.getCurrentDateTime();
        LocalDateTime startTime = LocalDateTime.of(currentDate, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(currentDate, LocalTime.MAX);
        LambdaQueryWrapper<DietRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DietRecord::getElderlyId, dinner.getElderId());
        wrapper.between(DietRecord::getCreatedTime, startTime, endTime);
        wrapper.eq(DietRecord::getDinnerFlag, 1);
        long res = super.count(wrapper);
        if (res > 0) {
            return Result.error("重复添加");
        }

        //将五个Food对象集合和一个Other对象集合转为数据库可存的DietRecord对象
        conversionTool(FoodType.FOOD.getValue(), dinner.getStapleFood(), elder.getElderlyId(),"dinner");
        conversionTool(FoodType.ASSISTED_FOOD.getValue(), dinner.getAssistedFood(), elder.getElderlyId(),"dinner");
        conversionTool(FoodType.MEAT.getValue(), dinner.getMeatDishs(), elder.getElderlyId(),"dinner");
        conversionTool(FoodType.VEGETABLE.getValue(), dinner.getVegetableDishs(), elder.getElderlyId(),"dinner");
        conversionTool(FoodType.SOUP.getValue(), dinner.getSoup(), elder.getElderlyId(),"dinner");
        //处理Others对象
        for (Others o : dinner.getOthers()) {
            DietRecord d = new DietRecord();
            //设置相关属性值
            d.setElderlyId(elder.getElderlyId());
            d.setOthers(o.getContent());
            d.setDinnerFlag(1);
            d.setDietType(FoodType.OTHERS.getValue());
            d.setPicture(o.getPicture());
            //存入数据库
            save(d);
        }
        return Result.success();
    }
    /**
     * 晚餐记录查询
     */
    @Override
    public Result getDinner(Long elderId, String date) {
        getElderlyInformation(elderId);

        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate d = LocalDate.parse(date, df);
        LocalDateTime startTime = LocalDateTime.of(d, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(d, LocalTime.MAX);

        //获取该老人的所有午餐记录
        QueryWrapper<DietRecord> qw = new QueryWrapper<>();
        qw.eq("elderly_id", elderId);
        qw.eq("dinner_flag", 1);
        qw.between("created_time", startTime, endTime);
        List<DietRecord> records = list(qw);

        //使用Map来进行按照创建时间分组
        Map<LocalDateTime, List<DietRecord>> recordsByTime = records.stream()
                .collect(Collectors.groupingBy(DietRecord::getCreatedTime));

        List<Dinner> dinnerList = new ArrayList<>();

        //遍历分组后的记录，构造dinner对象并添加到集合中
        for (Map.Entry<LocalDateTime, List<DietRecord>> entry : recordsByTime.entrySet()) {
            LocalDateTime createdTime = entry.getKey();
            List<DietRecord> recordsForTime = entry.getValue();

            //新建dinner对象并初始化
            Dinner dinner = new Dinner();
            dinner.setElderId(elderId);
            dinner.setCreatedTime(createdTime);
            dinner.setStapleFood(new ArrayList<>());
            dinner.setAssistedFood(new ArrayList<>());
            dinner.setMeatDishs(new ArrayList<>());
            dinner.setVegetableDishs(new ArrayList<>());
            dinner.setSoup(new ArrayList<>());
            dinner.setOthers(new ArrayList<>());

            for (DietRecord record : recordsForTime) {
                //根据record的dietType，将食物添加到对应的列表中
                switch (record.getDietType()) {
                    case -1:
                        Others other = new Others();
                        other.setId(record.getId());
                        other.setContent(record.getOthers());
                        other.setPicture(record.getPicture());
                        dinner.getOthers().add(other);
                        break;
                    case 2:
                        dinner.getStapleFood().add(createFoodFromRecord(record));
                        break;
                    case 3:
                        dinner.getAssistedFood().add(createFoodFromRecord(record));
                        break;
                    case 4:
                        dinner.getMeatDishs().add(createFoodFromRecord(record));
                        break;
                    case 5:
                        dinner.getVegetableDishs().add(createFoodFromRecord(record));
                        break;
                    case 6:
                        dinner.getSoup().add(createFoodFromRecord(record));
                        break;
                    default:
                        throw new ServiceException(Constants.CODE_500, "枚举类型错误");
                }
            }

            dinnerList.add(dinner);
        }

        //对dinner对象集合按创建时间排序
        Collections.sort(dinnerList);
        return Result.success(dinnerList);
    }

    /**
     * 早餐、晚餐对象装配
     * @param list     饮食记录列表
     * @param foodType 饮食类型
     */
    private <T> void getDietRecords(List<T> list,
                                    Integer foodType,
                                    List<DietRecord> dietRecords,
                                    long elderId,
                                    HttpServletRequest request) {
        String uri = request.getRequestURI();
        //对象封装
        if (list != null) {
            for (T item : list) {
                DietRecord dietRecord = new DietRecord();
                dietRecord.setElderlyId(elderId);
                dietRecord.setDietType(foodType);

                if (uri.contains("breakfast_add")) {
                    // 处理早餐相关逻辑
                    dietRecord.setBreakfastFlag(1);
                } else if (uri.contains("dinner_add")) {
                    // 处理晚餐相关逻辑
                    dietRecord.setDinnerFlag(1);
                }

                BeanUtils.copyProperties(item, dietRecord, "id");
                dietRecords.add(dietRecord);
            }
        }
    }

}
